/*
 * FileName: DataServiceImpl.java
 * Author:   zzw
 * Date:     2018年05月24日
 * Description:
 */
package com.chezhibao.trace.service.impl;

import com.chezhibao.trace.service.DataService;
import com.chezhibao.trace.vo.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.hadoop.hbase.HbaseTemplate;
import org.springframework.data.hadoop.hbase.RowMapper;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;

/**
 * 〈〉<br>
 * 〈〉
 *
 * @author zzw
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本]（可选）
 */
@Service
public class DataServiceImpl implements DataService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private HbaseTemplate hbaseTemplate;

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public ManyNodeTree getAll(String traceId) {
        logger.info("DataService getAll start......");
        final List<Message> list = new ArrayList<>();

        hbaseTemplate.get("trace", traceId, new RowMapper<List>() {
            @Override
            public List mapRow(Result result, int rowNum) throws Exception {
                for (Cell cell : result.rawCells()) {
                    String s = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());
                    Message message = null;
                    try {
                        String qualifer = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength());
                        message = objectMapper.readValue(s.getBytes(), Message.class);
                        message.setQualifer(qualifer);
                        if (3 == message.getRpcType()){
                            String[] split = message.getUserData().split("\u0014");
                            //msg.setUserData(split[split.length - 1].substring(0,split[split.length - 1].length() - 1));
                            String key = split[split.length - 1].substring(0,split[split.length - 1].length() - 1);
                            SqlVo sqlVo = hbaseTemplate.get("tracesql", key, new RowMapper<SqlVo>() {
                                @Override
                                public SqlVo mapRow(Result result, int i) throws Exception {
                                for (Cell cell2 : result.rawCells()) {
                                    String s = Bytes.toString(cell2.getValueArray(), cell2.getValueOffset(), cell2.getValueLength());
                                    return objectMapper.readValue(s.getBytes(), SqlVo.class);
                                }
                                return null;
                                }
                            });
                            if (sqlVo != null){
                                message.setSql(sqlVo.getSql());
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.info("read value error:" + s);
                    }
                    if(message != null){
                        list.add(message);
                    }
                }
                return list;
            }
        });


        if(list.size() > 0){
            int index = 0;

            //先找到根节点
            for (int i = 0;i < list.size();i++){
                int length = list.get(i).getRpcId().length();
                int length1 = list.get(index).getRpcId().length();
                if (length < length1){
                    index = i;
                }
            }

            ManyNodeTree tree = new ManyNodeTree(new Msg(list.get(index)));

            list.remove(index);

            tree.createTree3(list);

            Msg message = tree.getRoot().getData().getMessage();
            tree.iteratorTree(tree.getRoot(), message.getStartTime());

            if(message.getRpcType() != 0 && message.getRpcType() != 1 && message.getRpcType() !=2){
                //String s = message.getSpan().split(",")[1];
                message.setSpans(new String[]{"0", message.getSpan()});
            }
            else {
                message.setSpans(new String[]{"0", message.getSpan()});
            }

            String userData = message.getUserData();
            if(userData!= null && !"".equals(userData)){
                String s = userData.replaceAll("\u0014", "=").replaceAll("\u0012", "&");
                if("&".equals(s.substring(s.length() - 1))){
                    s = s.substring(0,s.length() - 1);
                    message.setUserData(s.substring(1));
                }
                else {
                    message.setUserData(s.substring(1));
                }
            }
            else {
                if (message.getUserData() == null || "".equals(message.getUserData())){
                    message.setUserData("");
                }
            }

            String serverData = message.getServerData();
            if(serverData!= null && !"".equals(serverData)){
                String s = serverData.replaceAll("\u0014", "=").replaceAll("\u0012", "&");
                if("&".equals(s.substring(s.length() - 1))){
                    s = s.substring(0,s.length() - 1);
                    message.setServerData(s.substring(1));
                }
                else {
                    message.setServerData(s.substring(1)    );
                }
            }
            else {
                if (message.getServerData() == null || "".equals(message.getServerData())){
                    message.setServerData("");
                }
            }

            String resultCode = message.getResultCode();

            if("200".equals(resultCode) || "00".equals(resultCode)){
                message.setResultCode("调用成功");
            }
            else {
                message.setResultCode("调用失败");
            }

            if(message.getTraceName() != null){
                message.setServiceName(message.getTraceName());
            }

            message.setTraceName("");

            if (message.getRemoteIp() == null){
                message.setRemoteIp("");
            }
            if ("null".equals(message.getRequestSize())){
                message.setRequestSize("");
            }
            if ("null".equals(message.getResponseSize())){
                message.setResponseSize("");
            }
            if (message.getMethodName() == null){
                message.setMethodName("");
            }
            logger.info("DataService getAll end......");
            return tree;
        }
        else {
            logger.info("DataService getAll end......");
            return null;
        }
    }

    @Override
    public List<Message> getData(String traceId) {
        final List<Message> list = new ArrayList<>();

        hbaseTemplate.get("trace", traceId, new RowMapper<List>() {
            @Override
            public List mapRow(Result result, int rowNum) throws Exception {
                for (Cell cell : result.rawCells()) {
                    String s = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());
                    Message message = null;
                    try {
                        //logger.info(s);
                        String qualifer = Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength());
                        message = objectMapper.readValue(s.getBytes(), Message.class);
                        message.setQualifer(qualifer);
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.info("read value error:" + s);
                    }
                    if(message != null){
                        list.add(message);
                    }
                }
                return list;
            }
        });
        return list;
    }

    @Override
    public SqlVo getSqlVo(String sqlId) {
        SqlVo sqlVo = hbaseTemplate.get("tracesql", sqlId, new RowMapper<SqlVo>() {
            @Override
            public SqlVo mapRow(Result result, int i) throws Exception {
                for (Cell cell : result.rawCells()) {
                    String s = Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength());
                    SqlVo sqlVo = null;
                    try {
                        sqlVo = objectMapper.readValue(s.getBytes(), SqlVo.class);
                    } catch (Exception e) {
                        e.printStackTrace();
                        logger.info("read value error:" + s);
                    }
                    if(sqlVo != null){
                        return sqlVo;
                    }
                }
                return null;
            }
        });
        return sqlVo;
    }

    @Override
    public List<SqlVo> listSqlVo() {
        return null;
    }

    public static void main(String[] args) {
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setConnectionRequestTimeout(100000000);
        requestFactory.setConnectTimeout(100000000);
        requestFactory.setReadTimeout(100000000);
        RestTemplate template = new RestTemplate(requestFactory);
        //template.set
        ParameterizedTypeReference<List<Message>> typeRef = new ParameterizedTypeReference<List<Message>>() {
        };
        ResponseEntity<List<Message>> responseEntity = template.exchange("http://clotho.mychebao.com/trace/download/0a640a8715473592025523643d40ed", HttpMethod.GET, null, typeRef);
        List<Message> list = responseEntity.getBody();
        if(list.size() > 0) {
            int index = 0;

            //先找到根节点
            for (int i = 0; i < list.size(); i++) {
                int length = list.get(i).getRpcId().length();
                int length1 = list.get(index).getRpcId().length();
                if (length < length1) {
                    index = i;
                }
            }

            ManyNodeTree tree = new ManyNodeTree(new Msg(list.get(index)));

            list.remove(index);

            tree.createTree3(list);

            Msg message = tree.getRoot().getData().getMessage();
            tree.iteratorTree(tree.getRoot(), message.getStartTime());

            if (message.getRpcType() != 0 && message.getRpcType() != 1 && message.getRpcType() != 2) {
                //String s = message.getSpan().split(",")[1];
                message.setSpans(new String[]{"0", message.getSpan()});
            } else {
                message.setSpans(new String[]{"0", message.getSpan()});
            }

            String userData = message.getUserData();
            if (userData != null && !"".equals(userData)) {
                String s = userData.replaceAll("\u0014", "=").replaceAll("\u0012", "&");
                if ("&".equals(s.substring(s.length() - 1))) {
                    s = s.substring(0, s.length() - 1);
                    message.setUserData(s.substring(1));
                } else {
                    message.setUserData(s.substring(1));
                }
            } else {
                if (message.getUserData() == null || "".equals(message.getUserData())) {
                    message.setUserData("");
                }
            }

            String serverData = message.getServerData();
            if (serverData != null && !"".equals(serverData)) {
                String s = serverData.replaceAll("\u0014", "=").replaceAll("\u0012", "&");
                if ("&".equals(s.substring(s.length() - 1))) {
                    s = s.substring(0, s.length() - 1);
                    message.setServerData(s.substring(1));
                } else {
                    message.setServerData(s.substring(1));
                }
            } else {
                if (message.getServerData() == null || "".equals(message.getServerData())) {
                    message.setServerData("");
                }
            }

            String resultCode = message.getResultCode();

            if ("200".equals(resultCode) || "00".equals(resultCode)) {
                message.setResultCode("调用成功");
            } else {
                message.setResultCode("调用失败");
            }

            if (message.getTraceName() != null) {
                message.setServiceName(message.getTraceName());
            }

            message.setTraceName("");

            if (message.getRemoteIp() == null) {
                message.setRemoteIp("");
            }
            if ("null".equals(message.getRequestSize())) {
                message.setRequestSize("");
            }
            if ("null".equals(message.getResponseSize())) {
                message.setResponseSize("");
            }
            if (message.getMethodName() == null) {
                message.setMethodName("");
            }
        }
    }
}
